package com.aigao.golf.common.datatable

import com.aigao.golf.Utils.RequestUtil
import com.aigao.golf.common.base.MyBaseService
import com.aigao.golf.common.result.ResultTo
import com.github.pagehelper.PageHelper
import com.github.pagehelper.PageInfo
import org.apache.commons.lang3.StringUtils
import org.slf4j.LoggerFactory
import tk.mybatis.mapper.entity.Example
import javax.servlet.http.HttpServletRequest
import java.lang.reflect.InvocationTargetException
import java.util.HashMap

/**
 * @author rankai
 * createTime 2017-04-2017/4/27 21:04
 */
class DataTablePage(private val baseService: MyBaseService<*>, private val clazz: Class<*>) {

    /**
     * 开始页
     */
    private var start = 0

    /**
     * 每页数
     */
    private var length = 10

    /**
     * 排序
     */
    private val orderBy: String


    private val request: HttpServletRequest = RequestUtil.request

    /**
     * 初始化数据
     */
    init {
        val start = this.request.getParameter(TableCode.PAGE_START_NAME)
        val length = this.request.getParameter(TableCode.PAGE_LENGTH_NAME)
        orderBy = this.request.getParameter(TableCode.PAGE_ORDER_NAME)
        this.start = if (start != null) Integer.parseInt(start) else this.start
        this.length = if (length != null) Integer.parseInt(length) else this.length
    }

    /**
     * 分页Base方法
     *
     * @return
     */
    fun pageList(): ResultTo {
        val example = buildExample(null, null)
        PageHelper.startPage<Any>(this.start, this.length)
        val list = this.baseService.selectByExample(example)
        return ResultTo().setData(PageInfo(list))
    }

    /**
     * 增加map参数
     *
     * @param parameterMap
     * @return
     */
    fun pageList(parameterMap: Map<String, Any>): ResultTo {
        val example = buildExample(null, parameterMap)
        PageHelper.startPage<Any>(this.start, this.length)
        val list = this.baseService.selectByExample(example)
        return ResultTo().setData(PageInfo(list))
    }

    /**
     * 自定义Example对象
     *
     * @param example
     * @return
     */
    fun pageList(example: Example): ResultTo {
        var example = example
        example = buildExample(example, null)
        PageHelper.startPage<Any>(this.start, this.length)
        val list = this.baseService.selectByExample(example)
        return ResultTo().setData(PageInfo(list))
    }

    /**
     * 自定义分页service,带自定义参数
     *
     * @param methodName
     * @param parameterMap
     * @return
     * @throws InvocationTargetException
     * @throws IllegalAccessException
     */
    @Throws(InvocationTargetException::class, IllegalAccessException::class)
    @JvmOverloads
    fun pageList(methodName: String, parameterMap: Map<String, Any>? = null): ResultTo {
        val map = requestToMap(parameterMap, true)
        PageHelper.startPage<Any>(this.start, this.length)
        val method = TableMethod.get(methodName)
        var list: List<*>? = null
        if (method != null) {
            list = method.invoke(baseService, map) as List<*>
        } else {
            log.warn("在DataPage中没有找到[$methodName]对应的方法")
        }
        return ResultTo().setData(PageInfo(list))
    }

    /**
     * 构建Example对象,传入的对象值后加#代表为模糊查询
     *
     * @param example
     * @param parameterMap
     * @return
     */
    private fun buildExample(example: Example?, parameterMap: Map<String, Any>?): Example {
        var example = example
        if (example == null) {
            example = Example(this.clazz)
        }
        val map = requestToMap(parameterMap, false)
        val criteria = example.createCriteria()
        for ((key, value1) in map) {
            val value = value1.toString()
            val charAt = value[value.length - 1]
            if (charAt == '#') {
                criteria.andLike(key, "%" + value.substring(0, value.length - 1) + "%")
            } else {
                criteria.andEqualTo(key, value1)
            }
        }
        if (StringUtils.isNotBlank(this.orderBy)) {
            val charAtOrder = orderBy[orderBy.length - 1]
            if (charAtOrder == '#') {
                example.orderBy(orderBy.substring(0, orderBy.length - 1)).desc()
            } else {
                example.orderBy(orderBy).asc()
            }
        }
        return example
    }

    /**
     * 将request参数转化为Map
     *
     * @param parameterMap
     * @return
     */
    private fun requestToMap(parameterMap: Map<String, Any>?, isMethod: Boolean): Map<String, Any> {
        val parameterNames = this.request.parameterNames
        val map = HashMap<String, Any>()
        while (parameterNames.hasMoreElements()) {
            val s = parameterNames.nextElement()
            if (StringUtils.isBlank(s) || TableCode.PAGE_START_NAME == s ||
                    TableCode.PAGE_LENGTH_NAME == s ||
                    TableCode.PAGE_ORDER_NAME == s) {
                continue
            }
            val parameter = this.request.getParameter(s)
            if (StringUtils.isNotBlank(parameter)) {
                log.debug("收到DateTale分页带搜索请求,搜索参数名:[$s],搜索参数值:[$parameter]")
                if (isMethod) {
                    val charAt = parameter[parameter.length - 1]
                    if (charAt == '#') {
                        map.put(s, parameter.substring(0, parameter.length - 1))
                        continue
                    }
                }
                map.put(s, parameter)
            }
        }
        if (parameterMap != null) {
            map.putAll(parameterMap)
        }
        return map
    }

    companion object {

        private val log = LoggerFactory.getLogger(DataTablePage::class.java)
    }
}
